package org.rendao.exception;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import org.apache.log4j.Logger;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;

public class TBFHandlerExceptionResolver extends
		AbstractHandlerExceptionResolver {

	private static final Logger logger = Logger
			.getLogger(TBFHandlerExceptionResolver.class);

	@Override
	protected ModelAndView doResolveException(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception exception) {

		TBFError error;
		if (exception instanceof TBFException) {
			error = ((TBFException) exception).getTbfError();
		} else {
			error = new TBFError(exception);
		}
		error.setMessage(exception.getMessage());
		logger.error(exception.getMessage(), exception);
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("exceptionMsg", serializeError(error));
		try {
			String xml = serializeError(error);
			response.setContentType("text/xml");
			PrintWriter out = response.getWriter();
			out.write(xml);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}

		return new ModelAndView();
	}

	private String serializeError(TBFError error) {
		try {
			JAXBContext context = JAXBContext.newInstance(TBFError.class);
			Marshaller m = context.createMarshaller();
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
			StringWriter sw = new StringWriter();
			m.marshal(error, sw);
			return sw.toString();
		} catch (JAXBException e) {
			return "<tbf_error/>";
		}
	}

}
